package net.xiaoxiangshop.controller.shop;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;

import net.xiaoxiangshop.Order;
import net.xiaoxiangshop.entity.*;
import net.xiaoxiangshop.service.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.fasterxml.jackson.annotation.JsonView;
import net.xiaoxiangshop.Pageable;
import net.xiaoxiangshop.Results;
import net.xiaoxiangshop.exception.ResourceNotFoundException;

/**
 * Controller - 商品
 */
@Controller("shopProductController")
@RequestMapping("/product")
public class ProductController extends BaseController {
    private static final Logger _logger = LoggerFactory.getLogger(ProductController.class);

    /**
     * ERP中台接口URL
     */
    @Value("${erp_basic_url}")
    private String erp_basic_url;

    /**
     * 最大对比商品数
     */
    public static final Integer MAX_COMPARE_PRODUCT_COUNT = 4;

    /**
     * 最大浏览记录商品数
     */
    public static final Integer MAX_HISTORY_PRODUCT_COUNT = 10;

    @Inject
    private ProductService productService;

    @Inject
    private NoteService noteService;

    @Inject
    private StoreService storeService;
    @Inject
    private ProductCategoryService productCategoryService;
    @Inject
    private StoreProductCategoryService storeProductCategoryService;
    @Inject
    private BrandService brandService;
    @Inject
    private ProductTagService productTagService;
    @Inject
    private AttributeService attributeService;
    @Inject
    private SearchService searchService;
    @Inject
    private UserService userService;


    /**
     * 添加对比
     */
    @GetMapping("/sync_product")
    public ResponseEntity<?> sync_product(Long productId) {

        Product product = productService.find(productId);

        Boolean isErp = product.getErpFlag();

        if (isErp) {
            productService.syncProducts(product);
        }

        return ResponseEntity.ok("");
    }

    /**
     * 详情 bn
     */
    @GetMapping("/detail/{productId}")
    public String detail(@PathVariable Long productId, ModelMap model) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        Product product = productService.find(productId);

//        Boolean isErp = product.getErpFlag();

//        if (isErp) {
//            productService.syncProducts(product);
//        }


        if (product == null || BooleanUtils.isNotTrue(product.getIsActive()) || BooleanUtils.isNotTrue(product.getIsMarketable())) {
            throw new ResourceNotFoundException();
        }

        String contents = "";

        String ids = product.getNoteIds();
        Date beginDate = product.getBeginDate();
        Date endDate = product.getEndDate();

        Date dt = new Date();
        if (null != ids && !ids.equals("")) {
            if (null != beginDate && null != endDate) {
                boolean diff_begin = beginDate.before(dt);
                boolean diff_end = endDate.after(dt);

                if (diff_begin && diff_end) {
                    String[] arrId = ids.split(",");
                    for (int i = 0; i < arrId.length; i++) {
                        Note note = noteService.find(Long.parseLong(arrId[i]));
                        if(note!=null){
                            contents += note.getContent();
                        }
                    }
                }
            }
        }

        product.setNoteContents(contents);

        Member currentUser = userService.getCurrent(Member.class);
        if (currentUser != null) {
            //会员等级ID
            product.setAttributeValue19(String.valueOf(currentUser.getMemberRank().getId()));
        }
        model.addAttribute("product", product);
//        if (product.getIsOutOfStock())
//            searchService.add(product);
        return "shop/product/detail";
    }

    /**
     * 对比栏
     */
    @GetMapping("/compare_bar")
    public ResponseEntity<?> compareBar(Long[] productIds) {
        List<Map<String, Object>> data = new ArrayList<>();
        if (ArrayUtils.isEmpty(productIds) || productIds.length > MAX_COMPARE_PRODUCT_COUNT) {
            return ResponseEntity.ok(data);
        }

        List<Product> products = productService.findList(productIds);
        for (Product product : products) {
            if (product != null && BooleanUtils.isTrue(product.getIsActive()) && BooleanUtils.isTrue(product.getIsMarketable())) {
                Map<String, Object> item = new HashMap<>();
                item.put("id", product.getId());
                item.put("name", product.getName());
                item.put("price", product.getPrice());
                item.put("marketPrice", product.getMarketPrice());
                item.put("thumbnail", product.getThumbnail());
                item.put("path", product.getPath());
                data.add(item);
            }
        }
        return ResponseEntity.ok(data);
    }

    /**
     * 添加对比
     */
    @GetMapping("/add_compare")
    public ResponseEntity<?> addCompare(Long productId) {
        Map<String, Object> data = new HashMap<>();
        Product product = productService.find(productId);
        if (product == null || BooleanUtils.isNotTrue(product.getIsActive()) || BooleanUtils.isNotTrue(product.getIsMarketable())) {
            return Results.UNPROCESSABLE_ENTITY;
        }

        data.put("id", product.getId());
        data.put("name", product.getName());
        data.put("price", product.getPrice());
        data.put("marketPrice", product.getMarketPrice());
        data.put("thumbnail", product.getThumbnail());
        data.put("path", product.getPath());
        return ResponseEntity.ok(data);
    }

    /**
     * 浏览记录
     */
    @GetMapping("/history")
    public ResponseEntity<?> history(Long[] productIds) {
        List<Map<String, Object>> data = new ArrayList<>();
        if (ArrayUtils.isEmpty(productIds) || productIds.length > MAX_HISTORY_PRODUCT_COUNT) {
            return ResponseEntity.ok(data);
        }

        List<Product> products = productService.findList(productIds);
        for (Product product : products) {
            if (product != null && BooleanUtils.isTrue(product.getIsActive()) && BooleanUtils.isTrue(product.getIsMarketable())) {
                Map<String, Object> item = new HashMap<>();
                item.put("id", product.getId());
                item.put("name", product.getName());
                item.put("price", product.getPrice());
                item.put("thumbnail", product.getThumbnail());
                item.put("path", product.getPath());
                data.add(item);
            }
        }
        return ResponseEntity.ok(data);
    }

    /**
     * 列表
     */
    @GetMapping("/list/{productCategoryId}")
    public String list(@PathVariable Long productCategoryId, Product.Type type, Store.Type storeType, Long brandId, Long productTagId, BigDecimal startPrice, BigDecimal endPrice, Boolean isOutOfStock, Product.OrderType orderType, Integer pageNumber, Integer pageSize,
                       HttpServletRequest request, ModelMap model) {
        ProductCategory productCategory = productCategoryService.find(productCategoryId);
        if (productCategory == null) {
            throw new ResourceNotFoundException();
        }

        Brand brand = brandService.find(brandId);
        ProductTag productTag = productTagService.find(productTagId);
        Map<Attribute, String> attributeValueMap = new HashMap<>();
        Set<Attribute> attributes = productCategory.getAttributes();
        if (CollectionUtils.isNotEmpty(attributes)) {
            for (Attribute attribute : attributes) {
                String value = request.getParameter("attribute_" + attribute.getId());
                String attributeValue = attributeService.toAttributeValue(attribute, value);
                if (attributeValue != null) {
                    attributeValueMap.put(attribute, attributeValue);
                }
            }
        }

        if (startPrice != null && endPrice != null && startPrice.compareTo(endPrice) > 0) {
            BigDecimal tempPrice = startPrice;
            startPrice = endPrice;
            endPrice = tempPrice;
        }

        Pageable pageable = new Pageable(pageNumber, pageSize);

        if(orderType==null){
            pageable.setOrderProperty("createdDate");
            pageable.setOrderDirection(Order.Direction.DESC);
        }

        model.addAttribute("orderTypes", Product.OrderType.values());
        model.addAttribute("productCategory", productCategory);
        model.addAttribute("type", type);
        model.addAttribute("storeType", storeType);
        model.addAttribute("brand", brand);
        model.addAttribute("productTag", productTag);
        model.addAttribute("attributeValueMap", attributeValueMap);
        model.addAttribute("startPrice", startPrice);
        model.addAttribute("endPrice", endPrice);
        model.addAttribute("endPrice", endPrice);
        model.addAttribute("isOutOfStock", isOutOfStock);
        model.addAttribute("orderType", orderType);
        model.addAttribute("pageNumber", pageNumber);
        model.addAttribute("pageSize", pageSize);
        model.addAttribute("page", productService.findPage(type, storeType, null, productCategory, null, brand, productTag, null, attributeValueMap, startPrice, endPrice, true, true, null, true, isOutOfStock, null,  orderType, pageable, null,null));
        return "shop/product/list";
    }

    /**
     * 列表
     */
    @GetMapping("/list")
    public String list(Product.Type type, Store.Type storeType, Long storeProductCategoryId, Long brandId,  Long productTagId, BigDecimal startPrice, BigDecimal endPrice, Boolean isOutOfStock, Product.OrderType orderType, Integer pageNumber, Integer pageSize, ModelMap model) {
        StoreProductCategory storeProductCategory = storeProductCategoryService.find(storeProductCategoryId);
        Brand brand = brandService.find(brandId);
        ProductTag productTag = productTagService.find(productTagId);

        if (startPrice != null && endPrice != null && startPrice.compareTo(endPrice) > 0) {
            BigDecimal tempPrice = startPrice;
            startPrice = endPrice;
            endPrice = tempPrice;
        }

        Pageable pageable = new Pageable(pageNumber, pageSize);
        model.addAttribute("orderTypes", Product.OrderType.values());
        model.addAttribute("type", type);
        model.addAttribute("storeType", storeType);
        model.addAttribute("storeProductCategory", storeProductCategory);
        model.addAttribute("brand", brand);
        model.addAttribute("productTag", productTag);
        model.addAttribute("startPrice", startPrice);
        model.addAttribute("endPrice", endPrice);
        model.addAttribute("isOutOfStock", isOutOfStock);
        model.addAttribute("orderType", orderType);
        model.addAttribute("pageNumber", pageNumber);
        model.addAttribute("pageSize", pageSize);
        model.addAttribute("page", productService.findPage(type, storeType, null, null, storeProductCategory, brand, productTag, null, null, startPrice, endPrice, true, true, null, true, isOutOfStock, null,  orderType, pageable, null,null));
        return "shop/product/list";
    }

    /**
     * 列表
     */
    @GetMapping(path = "/list", produces = MediaType.APPLICATION_JSON_VALUE)
    @JsonView(BaseEntity.BaseView.class)
    public ResponseEntity<?> list(Long productCategoryId, Product.Type type, Long storeProductCategoryId, Long brandId, Long productTagId, BigDecimal startPrice, BigDecimal endPrice, Product.OrderType orderType, Integer pageNumber, Integer pageSize, HttpServletRequest request) {
        ProductCategory productCategory = productCategoryService.find(productCategoryId);
        StoreProductCategory storeProductCategory = storeProductCategoryService.find(storeProductCategoryId);
        Brand brand = brandService.find(brandId);
        ProductTag productTag = productTagService.find(productTagId);
        Map<Attribute, String> attributeValueMap = new HashMap<>();
        if (productCategory != null) {
            Set<Attribute> attributes = productCategory.getAttributes();
            if (CollectionUtils.isNotEmpty(attributes)) {
                for (Attribute attribute : attributes) {
                    String value = request.getParameter("attribute_" + attribute.getId());
                    String attributeValue = attributeService.toAttributeValue(attribute, value);
                    if (attributeValue != null) {
                        attributeValueMap.put(attribute, attributeValue);
                    }
                }
            }
        }

        if (startPrice != null && endPrice != null && startPrice.compareTo(endPrice) > 0) {
            BigDecimal tempPrice = startPrice;
            startPrice = endPrice;
            endPrice = tempPrice;
        }

        Pageable pageable = new Pageable(pageNumber, pageSize);
        return ResponseEntity.ok(productService.findPage(type, null, null, productCategory, storeProductCategory, brand, productTag, null, attributeValueMap, startPrice, endPrice, true, true, null, true, null, null,  orderType, pageable, null,null).getContent());
    }

    /**
     * 搜索
     */
    @GetMapping("/search")
    public String search(String keyword, Store.Type storeType, Long storeId, Boolean isOutOfStock, BigDecimal startPrice, BigDecimal endPrice, Product.OrderType orderType, Integer pageNumber, Integer pageSize, ModelMap model) {
        if (StringUtils.isEmpty(keyword)) {
            return UNPROCESSABLE_ENTITY_VIEW;
        }

        if (startPrice != null && endPrice != null && startPrice.compareTo(endPrice) > 0) {
            BigDecimal tempPrice = startPrice;
            startPrice = endPrice;
            endPrice = tempPrice;
        }
        Store store = storeService.find(storeId);

        Pageable pageable = new Pageable(pageNumber, pageSize);
        model.addAttribute("orderTypes", Product.OrderType.values());
        model.addAttribute("productKeyword", keyword);
        model.addAttribute("storeType", storeType);
        model.addAttribute("store", store);
        model.addAttribute("isOutOfStock", isOutOfStock);
        model.addAttribute("startPrice", startPrice);
        model.addAttribute("endPrice", endPrice);
        model.addAttribute("orderType", orderType);
        model.addAttribute("searchType", "PRODUCT");
        model.addAttribute("page", productService.search(keyword, null, storeType, store, isOutOfStock, null, startPrice, endPrice, orderType, pageable));
        return "shop/product/search";
    }

    /**
     * 搜索
     */
    @GetMapping(path = "/search", produces = MediaType.APPLICATION_JSON_VALUE)
    @JsonView(BaseEntity.BaseView.class)
    public ResponseEntity<?> search(String keyword, Long storeId, BigDecimal startPrice, BigDecimal endPrice, Product.OrderType orderType, Integer pageNumber, Integer pageSize) {
        if (StringUtils.isEmpty(keyword)) {
            return Results.NOT_FOUND;
        }

        if (startPrice != null && endPrice != null && startPrice.compareTo(endPrice) > 0) {
            BigDecimal tempPrice = startPrice;
            startPrice = endPrice;
            endPrice = tempPrice;
        }
        Store store = storeService.find(storeId);

        Pageable pageable = new Pageable(pageNumber, pageSize);
        return ResponseEntity.ok(productService.search(keyword, null, null, store, null, null, startPrice, endPrice, orderType, pageable).getContent());
    }

    /**
     * 对比
     */
    @GetMapping("/compare")
    public String compare(Long[] productIds, ModelMap model) {
        if (ArrayUtils.isEmpty(productIds) || productIds.length > MAX_COMPARE_PRODUCT_COUNT) {
            return UNPROCESSABLE_ENTITY_VIEW;
        }

        List<Product> products = productService.findList(productIds);
        CollectionUtils.filter(products, new Predicate() {
            @Override
            public boolean evaluate(Object obj) {
                Product product = (Product) obj;
                return BooleanUtils.isTrue(product.getIsActive()) && BooleanUtils.isTrue(product.getIsMarketable());
            }
        });
        if (CollectionUtils.isEmpty(products)) {
            return UNPROCESSABLE_ENTITY_VIEW;
        }

        model.addAttribute("products", products);
        return "shop/product/compare";
    }

    /**
     * 点击数
     */
    @GetMapping("/hits/{productId}")
    public @ResponseBody
    Long hits(@PathVariable Long productId) {
        if (productId == null) {
            return 0L;
        }

        return productService.viewHits(productId);
    }

    /**
     * 每日商品同步
     */
    @GetMapping("sync_all_product_from_erp")
    public @ResponseBody
    void sync_all_product_from_erp() {
        productService.syncProducts(null);
    }

    /**
     * 点击数
     */
    @GetMapping("/sync_all_product_from_erp1/{productId}")
    public @ResponseBody
    void sync_all_product_from_erp1(@PathVariable Long productId) {
        productService.syncProducts(null,productId);
    }

}